package com.panfeng.xcloud.scheduler.util.tron;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.panfeng.xcloud.common.core.enums.ResponseStatusEnum;
import com.panfeng.xcloud.common.core.exceptions.BaseBizException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.tron.common.crypto.ECKey;
import org.tron.common.utils.ByteArray;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import static com.panfeng.xcloud.scheduler.util.tron.AddressHelper.addressBytesEncode58Check;


/**
 * @author: sunlight
 * @date: 2020/9/22 14:30
 */
public class Trc20Helper {
    public static TransactionResult transfer(
            String senderPrivateKey,
            String receiverAddress,
            BigDecimal value,
            String contractAddress,
            Long feeLimit) throws Exception {
        String result = TransactionSender.sendTransaction(
                senderPrivateKey,
                new Trc20TransferBuilder(
                        AddressHelper.privateKeyToBase58Address(senderPrivateKey),
                        receiverAddress,
                        value,
                        contractAddress,
                        feeLimit
                )
        );
        return TransactionResult.parse(result);
    }

    public static String privateKeyToBase58Address(String privateKey) {
        ECKey eCkey = ECKey.fromPrivate(ByteArray.fromHexString(privateKey));
        byte[] addressBytes = eCkey.getAddress();
        return addressBytesEncode58Check(addressBytes);
    }

    public static boolean hasTrxFee(String address, RestTemplate restTemplate) {
        String url = "https://api.trongrid.io/v1/accounts/" + address;
        JSONObject reqData = restTemplate.getForObject(url, JSONObject.class);
        if (reqData.getBoolean("success")) {
            JSONArray array = reqData.getJSONArray("data");
            if (array.size() > 0) {
                JSONObject data = (JSONObject) (array.get(0));
                BigDecimal balance = data.getBigDecimal("balance");
                if (balance.compareTo(BigDecimal.ZERO) > 0) {
                    return true;
                }
            }
            return false;
        }
        return false;
    }

    public static BigDecimal getTrc20Balance(String address, RestTemplate restTemplate) {
        String url = "https://api.trongrid.io/v1/accounts/" + address;
        JSONObject reqData = restTemplate.getForObject(url, JSONObject.class);
        if (reqData.getBoolean("success")) {
            JSONArray array = reqData.getJSONArray("data");
            if (array.size() > 0) {
                JSONObject data = (JSONObject) (array.get(0));
                //BigDecimal balance = ((JSONObject)(data.getJSONArray("trc20").get(0))).getBigDecimal("value");
                for (Object trc20 : data.getJSONArray("trc20")) {
                    JSONObject result = (JSONObject)trc20;
                    if(result.containsKey("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t")){
                        BigDecimal balance = result.getBigDecimal("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t");
                        return balance;
                    }
                }
            }
            throw new BaseBizException(ResponseStatusEnum.FAIL);
        }
        throw new BaseBizException(ResponseStatusEnum.FAIL);
    }

    public static Integer decimals(String ownerAddress, String contractAddress) throws Exception {
        String method = "decimals()";
        String response = triggerSmartContract(
                contractAddress,
                method,
                ownerAddress,
                null);
        JSONObject result = JSONObject.parseObject(response);
        String hexValue = result.getJSONArray("constant_result").getString(0);
        return TokenConverter.tokenHexValueToBigInteger(hexValue).intValue();
    }

    private static String triggerSmartContract(String contractAddress, String method, String ownerAddress, String parameter) throws Exception {
        Map<String, String> params = new HashMap<>();
        String hexOwnerAddress = AddressHelper.toHexString(ownerAddress);
        String hexContractAddress = AddressHelper.toHexString(contractAddress);
        params.put("contract_address", hexContractAddress);
        params.put("function_selector", method);
        params.put("parameter", parameter);
        params.put("owner_address", hexOwnerAddress);
        try {
            HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(params, HttpContext.standardHeaders);
            String route = "/wallet/triggersmartcontract";
            ResponseEntity<String> responseEntity = HttpContext.restTemplate.exchange(
                    SdkConfig.nodeServer + route, HttpMethod.POST, httpEntity, String.class);
            return responseEntity.getBody();
        } catch (Exception e) {
            throw e;
        }
    }

}
